using System;
using System.Reflection;
using System.Collections.Generic;
using System.Collections;

namespace Pitoshka.Tools.Helpers
{
	public class TemplateHelper
	{
		public static string FillTemplate(string template, string key, object CurrentObject)
		{
			return template.Replace("#" + key + "#", CurrentObject.ToString());
		}

		public static string FillTemplate(string template, object CurrentObject, List<Type> supportedTypes)
		{
			if (CurrentObject == null || template == null) return template;

			string result = template;
			string typeName = CurrentObject.GetType().Name;

			if (CurrentObject is string)
			{
				result = result.Replace("#" + typeName + "#", (string)CurrentObject);
			}
			else
			{
				List<Type> avaliableTypes = new List<Type>();
				avaliableTypes.Add(typeof(string));
				avaliableTypes.Add(typeof(int));
				avaliableTypes.Add(typeof(double));
				avaliableTypes.Add(typeof(bool));
				avaliableTypes.Add(typeof(DateTime));
				avaliableTypes.Add(typeof(DateTime?));

				PropertyInfo[] objectProperties = CurrentObject.GetType().GetProperties();
				foreach (PropertyInfo info in objectProperties)
				{
					if (info == null
						|| !info.CanRead
						|| info.MemberType != MemberTypes.Property)
						continue;

					if (avaliableTypes.Contains(info.PropertyType))
					{

						string value = string.Empty;
						object propertyValue = info.GetValue(CurrentObject, null);
						if (propertyValue != null)
						{
							if (info.PropertyType == typeof(double))
							{
								value = ((double)propertyValue).ToString("0.00");
							}
							else if (info.PropertyType == typeof(DateTime))
							{
								value = ((DateTime)propertyValue).ToShortDateString();
							}
							else if (info.PropertyType == typeof(DateTime?))
							{
								if (((DateTime?)propertyValue).HasValue)
									value = ((DateTime?)propertyValue).Value.ToShortTimeString();
							}
							else
							{
								value = propertyValue.ToString();
							}

						}

						result = result.Replace("#" + typeName + "." + info.Name + "#", value);
					}
					else if (supportedTypes.Contains(info.PropertyType))
					{
						string startTag = "<" + typeName + "." + info.Name + ">";
						string endTag = "</" + typeName + "." + info.Name + ">";

						while (result.IndexOf(startTag) != -1 &&
							result.IndexOf(endTag) != -1)
						{

							int start = result.IndexOf(startTag) + startTag.Length;
							int end = result.IndexOf(endTag);
							string innerTemplate = result.Substring(start, end - start); ;

							string outPut = "";
							object d = info.MemberType;

							
							
							outPut = FillMultyTemplate(innerTemplate,  info.GetValue(CurrentObject, null), supportedTypes);
							

							/*
							Type currentType = info.PropertyType.GetGenericArguments()[0];
							if (currentType == typeof(Roommates))
							{
								List<Roommates> objects = (List<Roommates>)info.GetValue(CurrentObject, null);
								outPut = FillTemplate(innerTemplate, objects);
							}
							else if (currentType == typeof(Accessory))
							{
								List<Accessory> objects = (List<Accessory>)info.GetValue(CurrentObject, null);
								outPut = FillTemplate(innerTemplate, objects);
							}
							*/

							result = result.Replace(startTag + innerTemplate + endTag, outPut);
						}
					}
				}
			}


			return result;
		}

		private static string FillMultyTemplate(string template, object objects, List<Type> supportedTypes)
		{
			if (objects == null)
				return template;

			string result = string.Empty;

			IEnumerable list = objects as IEnumerable;
			IEnumerator en = list.GetEnumerator();
			while (en.MoveNext())
			{
				result += FillTemplate(template, en.Current, supportedTypes);
			}

			return result;
		}
		public static string FillTemplate<T>(string template, List<T> objects, List<Type> supportedTypes)
		{
			if (objects == null)
				return template;

			string result = string.Empty;

			foreach (T obj in objects)
			{
				result += FillTemplate(template, obj, supportedTypes);
			}

			return result;
		}
	}
}
